// arp (address resolution protocol) header

#ifndef ARP_H
#define ARP_H

#include "eth.h"
#include "pack.h"
#include "pci.h"

// request and reply types
#define ARP_OP_REQUEST  0x0001
#define ARP_OP_REPLY    0x0002

// arp packet
struct arpPacket_t
{
    uint16_t hwType;
    uint16_t protocol;
    uint8_t hwSize;
    uint8_t protocolSize;
    uint16_t opcode;
    uint8_t hwSrc[6];
    uint8_t ipSrc[4];
    uint8_t hwDest[6];
    uint8_t ipDest[4];
}__attribute__((packed));

// handle an arp request
void handleArp( struct ethernet_t *eth, packet_t *pkt );

// arp cache entry - maps an IP to an ethernet addr
struct arpent
{
	uint32_t avail;
	uint32_t IP;
	uint8_t ethAddr[6];
};

// easy to type
typedef struct arpent arpent;

// ARP request wait-for data
struct arpreq_wait
{
	uint32_t code;
	uint32_t destip;
	uint32_t free;
	uint32_t waiting;
};

// easy to type
typedef struct arpreq_wait arpreq_wait;

// arp cache stuff
int checkArpCache( unsigned int myIp, arpent* myEnt );
int findClient( unsigned int myIp, arpent* myEnt );
void addEntToCache( arpent myEnt );
void ClearCache();

// displays the contents of the arp cache
void arpDisplayCache();

// sending arp requests
int waitForArpReply( int code );
void signalArpReply( int srcip );
/** this function does not return anything, just sends a request...
	doesn't wait either, so findClient is the better choice
	BUT this returns a code for using with wait* functions **/
int SendArpRequest( unsigned int destIp );

// intializes waiting
void InitArpReplyWait();

#endif // ARP_H
